////////////////////////////////////////////////////////////////////////////////

#ifndef _PHYSICSENGINE_H_
#define _PHYSICSENGINE_H_

////////////////////////////////////////////////////////////////////////////////

#ifndef _PHYSICS_H_
#include "physics.h"
#endif

#include <set>

////////////////////////////////////////////////////////////////////////////////

class Intersector;

////////////////////////////////////////////////////////////////////////////////

namespace PE
{
////////////////////////////////////////////////////////////////////////////////


/** Physics engine performs processing of all objects,
*   calculates positions and velocities, detects collisions.
*
*  @author   Anastasia Karpinska
*  @since    Sep 13th, 2009
*  @updated  Sep 14th, 2009
*/
class PhysicsEngine : public Physics
{
////////////////////////////////////////////////////////////////////////////////

public:

    /** Constructor */
    PhysicsEngine();


    /** Destructor */
    virtual ~PhysicsEngine();


    /** Adds new moving object */
    virtual void AddMovingObject( PhysicalObject& _object );


    /** Adds new stable object */
    virtual void AddStableObject( PhysicalObject& _object );


    /** Removes object */
    virtual void DeleteObject( PhysicalObject& _object );


    /** Updates objects states */
    virtual void Update(size_t _dt);


////////////////////////////////////////////////////////////////////////////////

private:

    /** Collection of physical objects */
    typedef std::set<PhysicalObject*> PhysicalObjects;


    /** Iterator for objects collection */
    typedef PhysicalObjects::const_iterator ObjectsIter;


    /** All moving physical objects */
    PhysicalObjects m_MovingObjects;


    /** All stable physical objects */
    PhysicalObjects m_StableObjects;

    
////////////////////////////////////////////////////////////////////////////////


    /** Calculates and updates object's position */
    void UpdatePosition( PhysicalObject& _obj, size_t _dt );


    /** Returns intersector for two objects */
    Intersector& GetIntersector( const PhysicalObject& _obj1,
                                 const PhysicalObject& _obj2 ) const;


    /** Process objects collisions */
    void ProcessCollisions();


    /** Apply impulse for two moving objects */
    void ApplyImpulse( PhysicalObject& _obj1, PhysicalObject& _obj2, Direction _impulseDir );


    /** Apply impulse for one object, when moving object collided with stable */
    void ApplyImpulse( PhysicalObject& _obj, Direction _impulseDir );


////////////////////////////////////////////////////////////////////////////////

};

////////////////////////////////////////////////////////////////////////////////

}; // namespace PE

////////////////////////////////////////////////////////////////////////////////

#endif
